package com.ridbor001.bank.service;// BankersAlgorithmService.java


import com.ridbor001.bank.bean.SafetyResult;
import com.ridbor001.bank.bean.SystemState;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class BankersAlgorithmService {

    public SafetyResult checkSafety(SystemState state) {
        int processCount = state.getProcessCount();
        int resourceTypeCount = state.getResourceTypeCount();

        // 初始化数据结构
        int[][] maxMatrix = to2DArray(state.getMaxMatrix());
        int[][] allocation = to2DArray(state.getAllocationMatrix());
        int[][] need = new int[processCount][resourceTypeCount];
        int[] available = state.getAvailableVector().stream().mapToInt(i -> i).toArray();

        boolean[] finish = new boolean[processCount];
        int[] work = Arrays.copyOf(available, available.length);
        List<Integer> safeSequence = new ArrayList<>();

        // 计算需求矩阵
        calculateNeedMatrix(maxMatrix, allocation, need, processCount, resourceTypeCount);

        // 安全性检查算法
        boolean found;
        do {
            found = false;
            for (int i = 0; i < processCount; i++) {
                if (!finish[i] && checkResourceAvailable(need[i], work, resourceTypeCount)) {
                    // 临时分配资源
                    for (int j = 0; j < resourceTypeCount; j++) {
                        work[j] += allocation[i][j];
                    }
                    finish[i] = true;
                    safeSequence.add(i);
                    found = true;
                }
            }
        } while (found);

        // 确定系统状态
        if (safeSequence.size() == processCount) {
            return new SafetyResult(true, safeSequence, null);
        } else {
            List<Integer> deadlockProcesses = new ArrayList<>();
            for (int i = 0; i < processCount; i++) {
                if (!finish[i]) deadlockProcesses.add(i);
            }
            return new SafetyResult(false, null, deadlockProcesses);
        }
    }

    public SafetyResult processRequest(SystemState state, int processId, List<Integer> request) {
        int processCount = state.getProcessCount();
        int resourceTypeCount = state.getResourceTypeCount();

        // 获取当前状态
        int[][] maxMatrix = to2DArray(state.getMaxMatrix());
        int[][] allocation = to2DArray(state.getAllocationMatrix());
        int[][] need = new int[processCount][resourceTypeCount];
        int[] available = state.getAvailableVector().stream().mapToInt(i -> i).toArray();

        // 保存原始状态以便回滚
        int[][] originalAllocation = deepCopy(allocation);
        int[] originalAvailable = Arrays.copyOf(available, available.length);

        // 检查请求是否超过Need
        calculateNeedMatrix(maxMatrix, allocation, need, processCount, resourceTypeCount);
        for (int j = 0; j < resourceTypeCount; j++) {
            if (request.get(j) > need[processId][j]) {
                throw new IllegalArgumentException("进程请求超过其最大需求");
            }
        }

        // 检查请求是否超过可用资源
        for (int j = 0; j < resourceTypeCount; j++) {
            if (request.get(j) > available[j]) {
                throw new IllegalArgumentException("请求超过系统可用资源");
            }
        }

        // 尝试分配资源
        for (int j = 0; j < resourceTypeCount; j++) {
            allocation[processId][j] += request.get(j);
            available[j] -= request.get(j);
        }

        // 更新状态以进行安全检查
        SystemState tempState = new SystemState();
        tempState.setProcessCount(processCount);
        tempState.setResourceTypeCount(resourceTypeCount);
        tempState.setMaxMatrix(state.getMaxMatrix());
        tempState.setAllocationMatrix(toListOfLists(allocation));
        tempState.setAvailableVector(toList(available));

        // 执行安全性检查
        SafetyResult result = checkSafety(tempState);

        // 如果不安全，则回滚操作
        if (!result.isSafe()) {
            state.setAllocationMatrix(toListOfLists(originalAllocation));
            state.setAvailableVector(toList(originalAvailable));
        }

        return result;
    }

    // 辅助方法
    private void calculateNeedMatrix(int[][] max, int[][] allocation, int[][] need,
                                     int processCount, int resourceTypeCount) {
        for (int i = 0; i < processCount; i++) {
            for (int j = 0; j < resourceTypeCount; j++) {
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }
    }

    private boolean checkResourceAvailable(int[] need, int[] work, int resourceTypeCount) {
        for (int j = 0; j < resourceTypeCount; j++) {
            if (need[j] > work[j]) {
                return false;
            }
        }
        return true;
    }

    private int[][] to2DArray(List<List<Integer>> list) {
        return list.stream()
                .map(l -> l.stream().mapToInt(Integer::intValue).toArray())
                .toArray(int[][]::new);
    }

    private List<List<Integer>> toListOfLists(int[][] array) {
        List<List<Integer>> result = new ArrayList<>();
        for (int[] row : array) {
            List<Integer> list = new ArrayList<>();
            for (int val : row) {
                list.add(val);
            }
            result.add(list);
        }
        return result;
    }

    private List<Integer> toList(int[] array) {
        List<Integer> list = new ArrayList<>();
        for (int val : array) {
            list.add(val);
        }
        return list;
    }

    private int[][] deepCopy(int[][] array) {
        int[][] copy = new int[array.length][];
        for (int i = 0; i < array.length; i++) {
            copy[i] = Arrays.copyOf(array[i], array[i].length);
        }
        return copy;
    }
}